package com.tongcao.cn.netty.aio;

import com.tongcao.cn.netty.Io;
import com.tongcao.cn.util.CalculatorUtil;

import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
import java.util.concurrent.ExecutionException;

/**
 * @author:tongcao
 * @since:2019/7/9 11:00
 * Description:
 */
public class AioHandler implements CompletionHandler<AsynchronousSocketChannel, AioServer>, Io {


    @Override
    public void completed(AsynchronousSocketChannel result, AioServer attachment) {
        // 当有下一个客户端接入的时候 直接调用Server的accept方法，这样反复执行下去，保证多个客户端都可以阻塞
        attachment.asynchronousServerSocketChannel.accept(attachment, this);
        read(result);
    }

    //读取数据
    private void read(final AsynchronousSocketChannel asynSocketChannel) {
        final ByteBuffer byteBuffer = ByteBuffer.allocate(BUFFER_SIZE);
        asynSocketChannel.read(byteBuffer, byteBuffer, new CompletionHandler<Integer, ByteBuffer>() {
            @Override
            public void completed(Integer result, ByteBuffer attachment) {
                //进行读取之后,重置标识位
                attachment.flip();
                //进行读取之后,重置标识位
                String resultData = new String(attachment.array()).trim();
                System.out.println("Server -> " + "收到客户端的数据信息为:" + resultData);
                String response = resultData + " = " + CalculatorUtil.cal(resultData);
                write(asynSocketChannel, response);
            }

            @Override
            public void failed(Throwable exc, ByteBuffer attachment) {
                exc.printStackTrace();
            }
        });
    }

    // 写入数据
    private void write(AsynchronousSocketChannel asynSocketChannel, String response) {
        try {
            final ByteBuffer byteBuffer = ByteBuffer.allocate(BUFFER_SIZE);
            byteBuffer.put(response.getBytes());
            byteBuffer.flip();
            asynSocketChannel.write(byteBuffer).get();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void failed(Throwable exc, AioServer attachment) {

    }


}